package com.nd.fastdp.workflow.service;

import com.nd.fastdp.org.service.DeptService;
import com.nd.fastdp.workflow.constant.*;
import com.nd.fastdp.workflow.convert.TaskConvert;
import com.nd.fastdp.workflow.dao.TaskMapper;
import com.nd.fastdp.workflow.model.bo.task.TaskBO;
import com.nd.fastdp.workflow.model.bo.undo.UndoBO;
import com.nd.fastdp.workflow.model.dto.task.TaskAddParam;
import com.nd.fastdp.workflow.model.dto.undo.UndoAddParam;
import com.nd.fastdp.workflow.model.entity.Task;
import com.nd.fastdp.workflow.serivce.ProcinstService;
import com.nd.fastdp.workflow.serivce.TaskService;
import com.nd.fastdp.workflow.serivce.UndoService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.Map;

@Service
public class TaskServiceImpl implements TaskService {

    @Autowired
    private TaskMapper taskMapper;

    @Autowired
    private UndoService undoService;

    @Autowired
    private ProcinstService procinstService;

    @Autowired
    private DeptService deptService;

    @Autowired
    private Map<String, WorkFlowListener> workFlowListenerMap;

    /**
     * 添加任务
     * @param param
     * @return
     */
    @Override
    @Transactional
    public TaskBO add(TaskAddParam param) {

        //-------------------------保存任务节点信息---开始------------------------
        Task task = new Task();

        task.setNodeName(param.getNode().getProperties().getTitle());
        task.setNodeId(param.getNode().getNodeId());
        task.setNodeCode(param.getNode().getProperties().getCode());
        task.setNodeType(param.getNode().getType());
        task.setProcinstId(param.getProcinstId());
        task.setCreateTime(System.currentTimeMillis());
        task.setAgreeNum(0);

        //抄送
        if(NodeTypes.NOTIFIER.getValue().equals(param.getNode().getType())){

            task.setMemberCount(param.getNode().getProperties().getMenbers().size());
            task.setUnCompleteNum(param.getNode().getProperties().getMenbers().size());

            task.setFinished(TaskFinishedFlagEnum.END.getValue());
            task.setState(TaskStateFlagEnum.COPY.getValue());
            task.setClaimTime(System.currentTimeMillis());

        }else{

            //合签
            if(CounterSignTypeEnum.YEST.getValue() == param.getNode().getProperties().getCounterSign()){

                task.setMemberCount(param.getNode().getProperties().getMenbers().size());
                task.setUnCompleteNum(param.getNode().getProperties().getMenbers().size());

            }else{
                task.setMemberCount(1);
                task.setUnCompleteNum(1);
            }

            task.setState(TaskStateFlagEnum.IN_APPROVAL.getValue());
            task.setCounterSign(CounterSignTypeEnum.YEST.getValue());
        }

        taskMapper.insert(task);
        //-------------------------保存任务节点信息---结束------------------------

        //-------------------------修改流程当前任务节点---开始------------------------
        procinstService.updateTask(param.getProcinstId(), task.getId());
        //-------------------------修改流程当前任务节点---结束------------------------

        //-------------------------添加待办任务---开始------------------------
        List<Map<String, Object>> menbers = param.getNode().getProperties().getMenbers();
        for (Map<String, Object> menber : menbers){

            UndoAddParam undoAddParam = new UndoAddParam();
            undoAddParam.setTaskId(task.getId());
            undoAddParam.setProcinstId(param.getProcinstId());
            undoAddParam.setUserId((String)menber.get("id"));
            undoAddParam.setUserName((String)menber.get("name"));
            undoAddParam.setDeptId((String)menber.get("dept"));
            undoAddParam.setDeptName(deptService.get(undoAddParam.getDeptId()).getName());

            undoService.add(undoAddParam);
        }

        //-------------------------添加待办任务---结束------------------------

        return TaskConvert.INSTANCE.to(task);
    }

    @Override
    public List<TaskBO> list(String procinstId) {

        List<Task> list = taskMapper.findByProcinstId(procinstId);

        List<TaskBO> result = TaskConvert.INSTANCE.to(list);

        for (TaskBO taskBO : result){
            taskBO.setUndos(undoService.listByTaskId(taskBO.getId()));
        }

        return result;
    }

    @Override
    public TaskBO get(String id){
        return TaskConvert.INSTANCE.to(taskMapper.selectById(id));
    }

    /**
     * 结束任务
     * @param id
     */
    @Override
    @Transactional
    public TaskBO finished(String id, Integer state){

        Task task = taskMapper.selectById(id);

        task.setClaimTime(System.currentTimeMillis());
        task.setFinished(TaskFinishedFlagEnum.END.getValue());
        task.setState(state);

        taskMapper.updateById(task);

        if(NodeTypes.NOTIFIER.getValue() != task.getNodeType()){

            List<UndoBO> undoList = undoService.listByProcinstId(task.getProcinstId());
            for (UndoBO undoBO : undoList){
                if(undoBO.getFinished() != UndoFinishedFlagEnum.PROCESSEND.getValue()){

                    undoService.finished(undoBO.getId(), UndoFinishedFlagEnum.PROCESSEND.getValue());
                }
            }
        }

        return TaskConvert.INSTANCE.to(task);
    }

    @Override
    public Integer addReadCount(String id) {

        Task targetTask = taskMapper.selectById(id);

        Task task = new Task();
        task.setId(id);
        task.setAgreeNum(targetTask.getAgreeNum() + 1);
        task.setUnCompleteNum(targetTask.getUnCompleteNum() - 1);

        taskMapper.updateById(task);

        return task.getUnCompleteNum();
    }

    @Override
    public Integer addAgreenCount(String id) {

        Task targetTask = taskMapper.selectById(id);

        Task task = new Task();
        task.setId(id);
        task.setAgreeNum(targetTask.getAgreeNum() + 1);
        task.setUnCompleteNum(targetTask.getUnCompleteNum() - 1);

        taskMapper.updateById(task);

        return task.getUnCompleteNum();
    }

}
